#include "FingerPrint-device.h"
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

FingerPrintDevice::FingerPrintDevice(const string &device)
    : uart(device, 57600)
{
}

// 发送消息
bool FingerPrintDevice::sendPacket(const vector<uint8_t> &packet)
{
	return uart.writeData(packet.data(), packet.size()) < 0 ? false : true;
}

// 接收消息
bool FingerPrintDevice::recvPacket(vector<uint8_t> &packet)
{
	// 读取固定9个字节最后2个字节为长度
	// 前9个长度写到packet1里边去
	vector<uint8_t> packet1(PACKET_FIX_LEN);
	int             ret = uart.readFixLenData(packet1.data(), packet1.size());
	if(ret < 0)
	{
		fprintf(stderr, "Fail to readFinxlenData\n");
		return false;
	}

	// 读取数据内容
	// 读取长度字段后边的内容
	FingerprintProtocol protocol = FingerprintProtocol::formProtocolPacket(packet1);
	vector<uint8_t>     packet2(protocol.getPacketDataLen() + 2);

	ret = uart.readFixLenData(packet2.data(), packet2.size());
	if(ret < 0)
	{
		fprintf(stderr, "Fail to readFinxlenData\n");
		return false;
	}

	packet.insert(packet.end(), packet1.begin(), packet1.end());
	packet.insert(packet.end(), packet2.begin(), packet2.end());

	return true;
}

// 创建捂手的包
bool FingerPrintDevice::handshake(void)
{
	// 请求包
	FingerprintProtocol reqProtocol = FingerprintProtocol::makeHandshakeProtocol();
	bool                ok          = sendPacket(reqProtocol.getPacket());
	// reqProtocol.showPacket();
	if(!ok)
	{
		fprintf(stderr, "Fail to sendPacket\n");
		return false;
	}

	// printf("--------------send packet--------------");
	// reqProtocol.showPacket();

	// 接收应答
	vector<uint8_t> ackPacket;
	ok = recvPacket(ackPacket);
	if(!ok)
	{
		fprintf(stderr, "Fail to recvPacket\n");
		return false;
	}

	// 校验接收数据是否正确
	FingerprintProtocol ackProtocol = FingerprintProtocol::formProtocolPacket(ackPacket);
	if(ackProtocol.isPacketError())
	{
		fprintf(stderr, "recv Packet is errror\n");
		return false;
	}

	// printf("--------------recv packet--------------");
	// ackProtocol.showPacket();

	return ackProtocol.getPacketData()[0] ? false : true;
}

// 3 探测手指
bool FingerPrintDevice::detectImage(void)
{
	// 请求包
	FingerprintProtocol reqProtocol = FingerprintProtocol::makeDetectImageProtocol();
	bool                ok          = sendPacket(reqProtocol.getPacket());
	// reqProtocol.showPacket();
	if(!ok)
	{
		fprintf(stderr, "Fail to sendPacket\n");
		return false;
	}

	// printf("--------------send packet--------------");
	// reqProtocol.showPacket();

	// 接收应答
	vector<uint8_t> ackPacket;
	ok = recvPacket(ackPacket);
	if(!ok)
	{
		fprintf(stderr, "Fail to recvPacket\n");
		return false;
	}

	// 校验接收数据是否正确
	FingerprintProtocol ackProtocol = FingerprintProtocol::formProtocolPacket(ackPacket);
	if(ackProtocol.isPacketError())
	{
		fprintf(stderr, "recv Packet is errror\n");
		return false;
	}

	// printf("--------------recv packet--------------");
	// ackProtocol.showPacket();

	return ackProtocol.getPacketData()[0] ? false : true;
}

/**
 * 生成特征码
 * @param bufferID
 * @return
 */
bool FingerPrintDevice::generateImageFeature(uint8_t bufferID)
{
	// 请求包
	FingerprintProtocol reqProtocol = FingerprintProtocol::makeImageFeatureProtocol(bufferID);
	bool                ok          = sendPacket(reqProtocol.getPacket());
	// reqProtocol.showPacket();
	if(!ok)
	{
		fprintf(stderr, "Fail to sendPacket\n");
		return false;
	}

	// printf("--------------send packet--------------");
	// reqProtocol.showPacket();

	// 接收应答
	vector<uint8_t> ackPacket;
	ok = recvPacket(ackPacket);
	if(!ok)
	{
		fprintf(stderr, "Fail to recvPacket\n");
		return false;
	}

	// 校验接收数据是否正确
	FingerprintProtocol ackProtocol = FingerprintProtocol::formProtocolPacket(ackPacket);
	if(ackProtocol.isPacketError())
	{
		fprintf(stderr, "recv Packet is errror\n");
		return false;
	}

	// printf("--------------recv packet--------------");
	// ackProtocol.showPacket();

	return ackProtocol.getPacketData()[0] ? false : true;
}

/**
 * 生成图像特征模版
 * @return
 */
bool FingerPrintDevice::generateImageTemplate(void)
{
	// 请求包
	FingerprintProtocol reqProtocol = FingerprintProtocol::makeImageTemplateProtocol();
	bool                ok          = sendPacket(reqProtocol.getPacket());
	// reqProtocol.showPacket();
	if(!ok)
	{
		fprintf(stderr, "Fail to sendPacket\n");
		return false;
	}

	// printf("--------------send packet--------------");
	// reqProtocol.showPacket();

	// 接收应答
	vector<uint8_t> ackPacket;
	ok = recvPacket(ackPacket);
	if(!ok)
	{
		fprintf(stderr, "Fail to recvPacket\n");
		return false;
	}
	// 校验接收数据是否正确
	FingerprintProtocol ackProtocol = FingerprintProtocol::formProtocolPacket(ackPacket);
	if(ackProtocol.isPacketError())
	{
		fprintf(stderr, "recv Packet is errror\n");
		return false;
	}
	// printf("--------------recv packet--------------");
	// ackProtocol.showPacket();
	return ackProtocol.getPacketData()[0] ? false : true;
}

/**
 * 存储模版
 */
bool FingerPrintDevice::storeImageTemplate(uint16_t pos)
{

	// 请求包
	FingerprintProtocol reqProtocol = FingerprintProtocol::makeStoreTemplateProtocol(pos);
	bool                ok          = sendPacket(reqProtocol.getPacket());
	// reqProtocol.showPacket();
	if(!ok)
	{
		fprintf(stderr, "Fail to sendPacket\n");
		return false;
	}

	// printf("--------------send packet--------------");
	// reqProtocol.showPacket();

	// 接收应答
	vector<uint8_t> ackPacket;
	ok = recvPacket(ackPacket);
	if(!ok)
	{
		fprintf(stderr, "Fail to recvPacket\n");
		return false;
	}
	// 校验接收数据是否正确
	FingerprintProtocol ackProtocol = FingerprintProtocol::formProtocolPacket(ackPacket);
	if(ackProtocol.isPacketError())
	{
		fprintf(stderr, "recv Packet is errror\n");
		return false;
	}
	// printf("--------------recv packet--------------");
	// ackProtocol.showPacket();
	return ackProtocol.getPacketData()[0] ? false : true;
}

bool FingerPrintDevice::recordFingerprint(uint16_t pos)
{
	bool ok = false;
	// ----------第一次探测手指----------
	for(int i = 0; i < 3; i++)
	{
		ok = detectImage();
		if(ok)
		{
			break;
		}
		sleep(1);
	}
	if(!ok)
	{
		return false;
	}
	// 生成特征码
	ok = generateImageFeature(0x1);
	if(!ok)
	{
		return false;
	}

	// ----------第二次探测手指----------
	for(int i = 0; i < 3; i++)
	{
		ok = detectImage();
		if(ok)
		{
			break;
		}
		sleep(1);
	}
	if(!ok)
	{
		return false;
	}
	// 生成特征码
	ok = generateImageFeature(0x2);
	if(!ok)
	{
		return false;
	}

	//----------存储模版-------------
	return storeImageTemplate(pos);
}

/**
 * 搜索指纹
 */
bool FingerPrintDevice::searchFingerPrint(uint16_t &pos)
{
	// 生成一个搜索指纹的包
	FingerprintProtocol reqProtocol = FingerprintProtocol::makeSearchFingerprintProtocol();
	bool                ok          = sendPacket(reqProtocol.getPacket());
	// reqProtocol.showPacket();
	if(!ok)
	{
		fprintf(stderr, "Fail to sendPacket\n");
		return false;
	}

	// printf("--------------send packet--------------");
	// reqProtocol.showPacket();

	// 接收应答
	vector<uint8_t> ackPacket;
	ok = recvPacket(ackPacket);
	if(!ok)
	{
		fprintf(stderr, "Fail to recvPacket\n");
		return false;
	}
	// 校验接收数据是否正确
	FingerprintProtocol ackProtocol = FingerprintProtocol::formProtocolPacket(ackPacket);
	if(ackProtocol.isPacketError())
	{
		fprintf(stderr, "recv Packet is errror\n");
		return false;
	}
	// printf("--------------recv packet--------------");
	// ackProtocol.showPacket();
	uint8_t *data = ackProtocol.getPacketData();
	if(data[0] != 0)
	{
		return false;
	}

	// 放回指纹的位置
	pos = (data[1] << 8 | data[2]);

	return true;
}

bool FingerPrintDevice::verfiyFingerPrint(uint16_t &pos)
{

	bool ok = false;
	for(int i = 0; i < 3; i++)
	{
		ok = detectImage();
		if(ok)
		{
			break;
		}
		sleep(1);
	}
	if(!ok)
	{
		return false;
	}
	// 生成特征码
	ok = generateImageFeature(0x1);
	if(!ok)
	{
		return false;
	}

	return searchFingerPrint(pos);
}

bool FingerPrintDevice::isTouchState(void)
{
	// 1,打开文件
	const char *filename = "/sys/class/gpio/gpio134/value";
	FILE *      fp       = fopen(filename, "r");
	if(!fp)
	{

		if(errno == ENOENT)
		{
			system("echo  134 > /sys/class/gpio/export");
			system(" echo in  > /sys/class/gpio/gpio134/direction");
			fp = fopen(filename, "r");
			if(!fp)
			{
				fprintf(stderr, "Fail to fopen:%s:%s\n", filename, strerror(errno));
				return false;
			}
		}
		else
		{
			fprintf(stderr, "Fail to fopen:%s:%s\n", filename, strerror(errno));
			return false;
		}
	}

	// 2 读取电平状态
	int level = fgetc(fp);
	fclose(fp);
	return level == '1' ? true : false;
}

bool FingerPrintDevice::deleteFingerprint(const uint16_t pos)
{
	FingerprintProtocol reqProtocol = FingerprintProtocol::makeDeleteFingerprintProtocol(pos);
	bool                ok          = sendPacket(reqProtocol.getPacket());
	if(!ok)
	{
		fprintf(stderr, "Fail to sendPacket\n");
		return false;
	}

#ifdef FINGERPRINT_DEVICE_DEBUG
	printf("----------send packet-------------\n");
	reqProtocol.showPacket();
#endif

	vector<uint8_t> ackPacket;
	ok = recvPacket(ackPacket);
	if(!ok)
	{
		fprintf(stderr, "Fail to recvPacket\n");
		return false;
	}

	FingerprintProtocol ackProtocol = FingerprintProtocol::formProtocolPacket(ackPacket);
	if(ackProtocol.isPacketError())
	{
		fprintf(stderr, "recv packet is error\n");
		return false;
	}

#ifdef FINGERPRINT_DEVICE_DEBUG
	printf("----------recv packet-------------\n");
	ackProtocol.showPacket();
#endif

	return ackProtocol.getPacketData()[0] ? false : true;
}

bool FingerPrintDevice::clearFingerprintLib(void)
{
	FingerprintProtocol reqProtocol = FingerprintProtocol::makeClearFingerprintLibProtocol();
	bool                ok          = sendPacket(reqProtocol.getPacket());
	if(!ok)
	{
		fprintf(stderr, "Fail to sendPacket\n");
		return false;
	}

#ifdef FINGERPRINT_DEVICE_DEBUG
	printf("----------send packet-------------\n");
	reqProtocol.showPacket();
#endif

	vector<uint8_t> ackPacket;
	ok = recvPacket(ackPacket);
	if(!ok)
	{
		fprintf(stderr, "Fail to recvPacket\n");
		return false;
	}

	FingerprintProtocol ackProtocol = FingerprintProtocol::formProtocolPacket(ackPacket);
	if(ackProtocol.isPacketError())
	{
		fprintf(stderr, "recv packet is error\n");
		return false;
	}

#ifdef FINGERPRINT_DEVICE_DEBUG
	printf("----------recv packet-------------\n");
	ackProtocol.showPacket();
#endif

	return ackProtocol.getPacketData()[0] ? false : true;
}
